package finance

import static groovyx.net.http.ContentType.HTML
import org.joda.time.*
import org.joda.time.format.*
import org.joda.time.contrib.hibernate.*
import org.apache.commons.math.stat.correlation.SpearmansCorrelation


class FieldValueController {
    def scaffold = true
   
    def getGoogleInstruments() { 
      def instruments = Instrument.findAll().findAll { 
         instrument -> instrument.source.name == 'Google Finance'
      }

      return instruments
    }

    def eodgoogle = {
      [instruments : getGoogleInstruments()]
    }

   def retrieve = {
      withAsyncHttp(poolSize : 4, uri : "http://finance.google.com", contentType : HTML) { 
         def result = get(path:'/finance/historical', query: [q:params.symbol, output:'csv']) { 
            resp, html ->  println ' got async response!' 
            return html
         } 

         assert result instanceof java.util.concurrent.Future

         while (! result.done) { 
            Thread.sleep(2000) 
         }

         def html = result.get().toString()
         
         for(line in html.split('\n')) {
            if(!line.contains('Date')) {
               def fields = line.split(',')
               def dateTime = DateTimeFormat.forPattern("dd-MMM-yy").parseDateTime(fields[0])
               def instrument = Instrument.findBySymbol(params.symbol)
               saveValueByFieldName('Open', dateTime, instrument, fields[1])
               saveValueByFieldName('High', dateTime, instrument, fields[2])
               saveValueByFieldName('Low', dateTime, instrument, fields[3])
               saveValueByFieldName('Close', dateTime, instrument, fields[4])
               saveValueByFieldName('Volume', dateTime, instrument, fields[5])
            }
         }
      }
   }

   def saveValueByFieldName(fieldName, dateTime, instrument, val) {
         def mnemonic = Field.findByName(fieldName)
         def fVal = new FieldValue(added: dateTime, val: val, instrument: instrument, field:mnemonic).save();
   }

   def historicalChart = {
     if(params.fieldVar == null) {
         return [instruments : getGoogleInstruments()]
      } else {
         def instrument = Instrument.findBySymbol(params.select1)
         def instrument2 = Instrument.findBySymbol(params.select2)
		 def field = Field.findByName(params.fieldVar)
		 def firstData = getDataForInstrument(instrument, field)
		 def secondData = getDataForInstrument(instrument2, field)
		 
		 def data1 = [:]
		 def data2 = [:]
		 def xLabels = []
		 
		 for(def added : firstData?.keySet()){
			if( secondData?.keySet()?.contains(added)) {
				def shortKey = added.toString("MMM yy")
				
				if(!xLabels.contains(shortKey)) {
					xLabels << shortKey	
				}
				
				data1[added] = Double.valueOf(firstData?.get(added))
				data2[added] = Double.valueOf(secondData?.get(added))
			}
		 }
		
         return [instruments : getGoogleInstruments(),
			 firstData : data1,
			 secondData : data2,
			 xLabels : xLabels]
      }
   }
   
   def getDataForInstrument(instrument, field) {
         def fieldVals = FieldValue.findAllByInstrumentAndField(instrument, field)
		 def data = [:]
		 
		 for(int i = 0; i < fieldVals.size(); i++) {
			data[fieldVals[i].added] = fieldVals[i].val 
		 }
		 
		 return data.sort { it.key }
   }
   
   def correlation = {
	   if(params.select1 != null) { 
		   return [instruments : getGoogleInstruments(),
			   open: correlate(params.select1, params.select2, 'Open'),
			   high: correlate(params.select1, params.select2, 'High'),
			   low: correlate(params.select1, params.select2, 'Low'),
			   close: correlate(params.select1, params.select2, 'Close'),
			   volume: correlate(params.select1, params.select2, 'Volume')
	   		]
	   } else {
         return [instruments : getGoogleInstruments()]
	   }
   }
   
   def correlate(symbol1, symbol2, fieldName) {
	       def instrument = Instrument.findBySymbol(symbol1)
	       def instrument2 = Instrument.findBySymbol(symbol2)
		   def field = Field.findByName(fieldName)
		   def firstData = getDataForInstrument(instrument, field)
		   def secondData = getDataForInstrument(instrument2, field)
			 
			 def data1 = []
			 def data2 = []
			 
			 for(def added : firstData?.keySet()){
				if( secondData?.keySet()?.contains(added)) {
					data1 << Double.valueOf(firstData?.get(added))
					data2 << Double.valueOf(secondData?.get(added))
				}
		 }
		   
		 return new SpearmansCorrelation().correlation((double[])data1.toArray(), 
			   (double[])data2.toArray())
   }
}
